package com.xwj.Handler;

import com.xwj.config.ThreadPoolConfig.TaskThreadPoolConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 线程池优雅停机(等效于以下两行代码)
 * 不再在线程池中配置以下两行
 * executor.setWaitForTasksToCompleteOnShutdown(true);
 * executor.setAwaitTerminationSeconds(threadPoolConfig.getAwaitTerminationSeconds());
 * 线程池优雅停机处理：spring销毁bean和上下文之前
 */
@Slf4j
@Component
public class ThreadPoolContextClosedHandler {

    @Autowired
    private TaskThreadPoolConfig threadPoolConfig;
    @Autowired
    private ThreadPoolTaskExecutor registerTaskAsyncPool;
    @Autowired
    private ThreadPoolTaskExecutor houseInfoTaskAsyncPool;
    @Autowired
    private ThreadPoolTaskExecutor orderInfoTaskAsyncPool;
    @Autowired
    private ThreadPoolTaskExecutor fileUploadoTaskAsyncPool;
    @Autowired
    private ThreadPoolTaskExecutor repairTaskAsyncPool;

    public void onApplicationEvent() {
        shutdownAndAwaitTermination(registerTaskAsyncPool.getThreadPoolExecutor());
        shutdownAndAwaitTermination(houseInfoTaskAsyncPool.getThreadPoolExecutor());
        shutdownAndAwaitTermination(orderInfoTaskAsyncPool.getThreadPoolExecutor());
        shutdownAndAwaitTermination(fileUploadoTaskAsyncPool.getThreadPoolExecutor());
        shutdownAndAwaitTermination(repairTaskAsyncPool.getThreadPoolExecutor());
    }

    private void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); //不接受新任务
        try {//等待现有任务终止
            if (!pool.awaitTermination(threadPoolConfig.getAwaitTerminationSeconds(), TimeUnit.SECONDS)) {
                pool.shutdownNow();//取消当前正在执行的任务
                if (!pool.awaitTermination(threadPoolConfig.getAwaitTerminationSeconds(), TimeUnit.SECONDS)) //等待任务被取消做出的响应
                    log.error("msg:{}", "线程池没有终止");
            }
        } catch (InterruptedException ie) {
            pool.shutdownNow(); //如果当前线程中断则取消任务
            Thread.currentThread().interrupt(); //保持中断状态
        }
    }
}
